home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
amok_lha
/
amok82.lha
/
Mini
/
txt
/
Parser.mod
< prev
next >
Wrap
Text File
|
1993-08-15
|
3KB
|
87 lines
MODULE Parser;
IMPORT S := Scanner, R := Requests, Code;
PROCEDURE Chk(sym: INTEGER; msg: ARRAY OF CHAR);
BEGIN IF S.sym=sym THEN S.GetSym ELSE R.Fail(msg) END END Chk;
PROCEDURE VarDeclaration;
(* VarDeclaration -> VAR Identifier {"," Identifier} . *)
BEGIN
REPEAT
S.GetSym;
IF S.sym#S.ident THEN R.Fail("Bezeichner in erwartet!") END;
Code.DCL(S.identifier);
S.GetSym;
UNTIL S.sym#S.comma;
END VarDeclaration;
PROCEDURE Factor;
(* Factor -> Identifier | Constant . *)
BEGIN
CASE S.sym OF
| S.ident : Code.MOVEvarD0 (S.identifier); S.GetSym;
| S.const : Code.MOVEconstD0(S.constant ); S.GetSym;
ELSE R.Fail("Faktor erwartet") END;
END Factor;
PROCEDURE Expression;
(* Expression -> [ "+" | "-" ] Factor { ( "+" | "-" ) Factor } . *)
VAR neg: BOOLEAN; (* muß D0 negiert werden? *)
BEGIN
neg := FALSE;
IF S.sym IN {S.plus,S.minus} THEN neg := S.sym=S.minus; S.GetSym END;
Factor;
IF neg THEN Code.NEGD0 END;
WHILE S.sym IN {S.plus,S.minus} DO
neg := S.sym=S.minus; S.GetSym;
Code.MOVED0D1;
Factor;
IF neg THEN Code.NEGD0 END;
Code.ADDD1D0;
END;
END Expression;
PROCEDURE Statement;
(* Statement -> Assignment | While | Print . *)
(* Assignment -> Identifer "=" Expression . *)
(* While -> WHILE Expression DO { Statement } END . *)
(* Print -> PRINT Expression *)
VAR
varname: S.Identifier; (* Ziel einer Zuweisung *)
start,end : INTEGER; (* Labels bei einer Schleife *)
BEGIN
CASE S.sym OF
| S.ident: varname := S.identifier; S.GetSym; (* Zuweisung *)
Chk(S.equal,"'=' erwartet!");
Expression;
Code.MOVED0var(varname);
| S.while: S.GetSym; (* Schleife *)
start := Code.GetLabel(); end := Code.GetLabel();
Code.Label(start);
Expression;
Chk(S.do,"DO erwartet!");
Code.TSTD0; Code.BLE(end);
WHILE S.sym#S.end DO Statement END;
Chk(S.end,"END erwartet!");
Code.BRA(start); Code.Label(end);
| S.print: S.GetSym; Expression; Code.PrintD0; (* Ausgabe *)
ELSE R.Fail("Statement erwartet!") END;
END Statement;
PROCEDURE Program*;
(* Program -> PROGRAM [ VarDeclaration ] BEGIN { Statement } END. *)
VAR start: INTEGER;
BEGIN
S.GetSym; Chk(S.program,"PROGRAM erwartet!");
start := Code.GetLabel(); Code.BRA(start);
IF S.sym=S.var THEN VarDeclaration END;
Chk(S.begin,"BEGIN erwartet!");
Code.StartUp(start);
WHILE S.sym#S.end DO Statement END;
Code.CleanUp;
Chk(S.end,"END erwartet!");
END Program;
END Parser.